﻿using System;
using System.Xml.Linq;
using System.Linq;
using TVersityDotNet.HelperTypes;
using System.Globalization;
using TVersityDotNet.Status;

namespace TVersityDotNet.Responses
{
    public class StatusFetchResponse : TVersityResponse
    {
        public TVStatus Status { get; set; }

        //TODO: remove calls to virtuals from within constructors (bug: 28027)
        public StatusFetchResponse(XDocument xmlDocument)
        {
            if (xmlDocument != null)
            {
                this.Status = new TVStatus();
                this.ParseMessage(xmlDocument);
            }
            else
            {
                this.ResponseSuccess = false;
                this.ResponseMessage = "Incomming xmlDocument was null";
            }
        }

        public override void ParseMessage(XDocument responseXml)
        {
            if (responseXml != null)
            {
                base.ParseMessage(responseXml);
                
                // Messages
                var queryMessages = from result in responseXml.Descendants("message")
                            select new StatusMessage(                          
                                int.Parse(result.Attribute("code").Value, CultureInfo.InvariantCulture),
                                result.Attribute("category").Value,                                
                                result.Attribute("text").Value,
                                TimeSpan.Parse(result.Attribute("time").Value, CultureInfo.InvariantCulture));

                foreach (StatusMessage sm in queryMessages)
                {
                    this.Status.Messages.Add(sm);
                }
                
                // Players with no profile ID
                var queryPlayers =  from result in responseXml.Descendants("player")
                                    where result.Attribute("profileID") == null
                                    select new StatusPlayer(
                                        result.Attribute("playerID").Value,
                                        result.Attribute("icon").Value,
                                        result.Attribute("name").Value,
                                        result.Attribute("longName").Value,                                        
                                        result.Attribute("IP").Value);

                foreach (StatusPlayer sp in queryPlayers)
                {
                    this.Status.Players.Add(sp);
                }

                // Players with profile ID
                queryPlayers = from result in responseXml.Descendants("player")
                                   where result.Attribute("profileID") != null
                                   select new StatusPlayer(
                                       result.Attribute("playerID").Value,
                                       result.Attribute("icon").Value,
                                       result.Attribute("name").Value,
                                       result.Attribute("longName").Value,
                                       result.Attribute("profileID").Value,
                                       result.Attribute("IP").Value);

                foreach (StatusPlayer sp in queryPlayers)
                {
                    this.Status.Players.Add(sp);
                }

                // Streams 
                var queryStreams = from result in responseXml.Descendants("stream")
                                   select new StatusStream
                                   {
                                       Url = new Uri(result.Attribute("url").Value),
                                       Title = result.Attribute("title").Value,
                                       PlayerId = result.Attribute("playerID").Value,
                                       Icon = result.Attribute("icon").Value,
                                       Name = result.Attribute("name").Value,
                                       LongName = result.Attribute("longName").Value,
                                       SourceMimeType = result.Attribute("sourceMimetype").Value,
                                       SourceFormat = result.Attribute("sourceFormat").Value,
                                       ProfileId = result.Attribute("profileID").Value,
                                       Progress = int.Parse(result.Attribute("progress").Value, CultureInfo.InvariantCulture),
                                       Size = int.Parse(result.Attribute("size").Value, CultureInfo.InvariantCulture)
                                   };

                foreach (StatusStream ss in queryStreams)
                {
                    this.Status.Streams.Add(ss);
                }

                // Transcodes 
                var queryTranscode = from result in responseXml.Descendants("transcode")
                                    select new StatusTranscode
                                   {
                                       Url = new Uri(result.Attribute("url").Value),
                                       Title = result.Attribute("title").Value,
                                       SourceMimeType = result.Attribute("sourceMimetype").Value,
                                       SourceFormat = result.Attribute("sourceFormat").Value,
                                       TargetFormat = result.Attribute("targetFormat").Value,
                                       TargetMimeType = result.Attribute("targetMimeType").Value,
                                       Progress = int.Parse(result.Attribute("progress").Value, CultureInfo.InvariantCulture),
                                       Size = int.Parse(result.Attribute("size").Value, CultureInfo.InvariantCulture),
                                       TranscodeStatus =  StatusTranscodeStatus.Active                                       
                                   };

                foreach (StatusTranscode st in queryTranscode)
                {
                    this.Status.Transcodes.Add(st);
                }

                // Transcodes 
                var queryDownloads = from result in responseXml.Descendants("download")
                                     select new StatusDownload
                                     {
                                         Url = new Uri(result.Attribute("url").Value),
                                         Progress = int.Parse(result.Attribute("progress").Value, CultureInfo.InvariantCulture),
                                         Size = int.Parse(result.Attribute("size").Value, CultureInfo.InvariantCulture),
                                         File = result.Attribute("file").Value
                                     };

                foreach (StatusDownload sd in queryDownloads)
                {
                    this.Status.Downloads.Add(sd);
                }
            }
            else
            {
                this.ResponseSuccess = false;
                this.ResponseMessage = "Provided responseXml was null";
            }        
        }
    }    
}
